package 
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import Buttons.*;
	import flash.text.engine.CFFHinting;
	/**
	 * ...
	 * @author Lokiraze
	 */
	public class Game extends MovieClip 
	{
		public var btnNumber:Array = new Array();
		
		public var hints:Hint;
		public var solved:Solve;
		public var resets:Reset;
		public var newG:NewGame;
		public var checked:Check;
		
		public var Grid:Array = new Array();
		public var gridCells:Array = new Array();
		public var playerAnswer:int;
		
		public function Game()
		{
			StartGame();
			
		}
		
		public function StartGame()
		{
			SetUp();
			GeneratePuzzle();
			
			var revealed:int = 50;

			while(revealed > 0)
			{
				var i = Random(0, 8);
				var k = Random(0, 8);

				if(Grid[i][k].revealed == false)
				{
						Grid[i][k].revealed = true;
						Grid[i][k].ShowAnswer("Initial");
						revealed--;
				}
			}
			
			SetUpEvents();
			
			hints = new Hint(this); 
			solved = new Solve(this);
			resets = new Reset(this);
			newG = new NewGame(this);
			checked = new Check(this);
			
			AddChildren();

		}
		
		public function SetUp()
		{
			var gridIndex:int = 0;
			var c:Cell;
			for (var i:int = 0; i < 9; i ++)
			{
				Grid[i] = new Array();
				for (var j:int = 0; j < 9; j++)
				{
					c = new Cell(i, j);
					Grid[i][j] = c;
					gridCells[gridIndex] = c;
					gridCells[gridIndex].answer = 0;
					gridIndex ++;
				}
			}
		}
		
		public function SetUpEvents()
		{
			for (var i:int = 0; i < gridCells.length; i++)
			{
				if (!gridCells[i].revealed)
				{
					gridCells[i].buttonMode = true;
					gridCells[i].addEventListener(MouseEvent.CLICK, PuttingAnswers);
				}
			}
		}
		
		public function PuttingAnswers(e:MouseEvent)
		{
			var index:int = gridCells.indexOf(e.currentTarget)
			gridCells[index].setPlayerInput(playerAnswer);
		}
		
		public function AddChildren():void
		{
			for (var i:int = 0; i < 9; i ++)
			{
				for (var j:int = 0; j < 9; j++)
				{
					Grid[i][j].x = j * Grid[i][j].width;
					Grid[i][j].y = i * Grid[i][j].height;
					addChild(Grid[i][j]);
				}
			}
			
			for (var k:int = 0; k < 9; k++)
			{
				btnNumber[k] = new NumberButton(k+1,this);
				btnNumber[k].x = 17.5 + (k * (btnNumber[k].width + 17.5));
				btnNumber[k].y = (Grid[8][8].y + Grid[8][8].height) + 30;
				addChild(btnNumber[k]);
			}
			
			hints.x = Grid[0][8].x + Grid[0][8].width + 30; 
			solved.x = Grid[0][8].x + Grid[0][8].width + 30;
			resets.x =  Grid[0][8].x + Grid[0][8].width + 30;
			newG.x =  Grid[0][8].x + Grid[0][8].width + 30;
			checked.x =  Grid[0][8].x + Grid[0][8].width + 30;
			hints.y = 40;
			solved.y = 80;
			resets.y = 120;
			newG.y = 160;
			checked.y = 200;
			addChild(hints);
			addChild(solved);
			addChild(resets);
			addChild(newG);
			addChild(checked);
		}
		
		public function GeneratePuzzle():void
		{
			var index:int = 0;

			while(index < 81)
			{
				var number:int = 0;
				var values:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9];

				while(values.length > 0 && number == 0)
				{
					var zindex:int = Random(0,  values.length);
					var z:int = values[zindex];
					values.splice(zindex, 1);
		
					if(!Conflicts(z, gridCells[index]))
					{
						number = z;
					}
				}
				
				if(number == 0)
				{
					var maxbacktrack:int = index > 10 ? 10 : index;
					var backtrack:int = Random(1, maxbacktrack);
					var backtracked:int = 0;

					while(backtracked < backtrack)
					{
						gridCells[index - backtracked].answer = 0;
						backtracked++;
					}

					index -= backtrack;
				}
				else
				{
					
					gridCells[index].answer = number;
					index++;
				}
			}
		}
		
		public function Conflicts(number:int, cell:Cell):Boolean
		{
			// Check the rows and columns
			for(var i:int = 0; i < 9; i++)
			{
				if(Grid[cell.xPos][i].answer == number || Grid[i][cell.yPos].answer == number)
				{
						return true;
				}
			}
			//cell.Debug();
			// Check the region it's in
			for(var j:int=cell.row; j<cell.row+3; j++)
			{
				for(var k:int=cell.column; k<cell.column+3; k++)
				{
					if(Grid[j][k].answer == number)
					{
							return true;
					}
				}
			}

			return false;
		}
		
		public function SetPlayerAnswer(s:int):void
		{
			playerAnswer = s;
		}
		
		public function getPlayerAnswer():int
		{
			return playerAnswer;
		}
		
		public function Random(min:int, max:int):int
		{
			var number:int = min - 1;

			while(number < min || number > max)
			{
					number = min + Math.round(Math.random() * (max - min));
			}

			return number;
		}
	}
	
}